﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using ShapeDemo.UC.WinProp;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Input;

namespace ShapeDemo
{
    public class PolylineDrawer
    {
        public Canvas PolylineCanvas { get; set; }
        public List<ASPNETX_WPFPolyline> PolylineCollection { get; set; }

        private WinPropPolyline winPolylineProp;
        private WinPropCommon winCommonProp;
        
        ASPNETX_WPFPolyline plBody;
        private TMouse _MouseType;
        public TMouse MouseTye
        {
            get
            {
                return _MouseType;
            }
            set
            {
                switch (value)
                {
                    case TMouse.Drawing:

                        PolylineCanvas.Cursor = Cursors.Cross;

                        foreach (ASPNETX_WPFPolyline item in PolylineCollection)
                        {
                            item.PolylineBody.Cursor = Cursors.Cross;
                        }

                        _MouseType = value;

                        RegistContextMenu();

                        break;
                    case TMouse.Point:

                        PolylineCanvas.Cursor = Cursors.Arrow;

                        foreach (ASPNETX_WPFPolyline item in PolylineCollection)
                        {
                            item.PolylineBody.Cursor = Cursors.Hand;
                            item.PolylineBody.MouseLeftButtonDown += new MouseButtonEventHandler(polylineCanvas_MouseLeftButtonDown);
                        }

                        _MouseType = value;

                        RegistContextMenu();

                        break;
                }
            }
        }

        public bool IsShiftDown { get; set; }

        private ContextMenu cMenu = new ContextMenu();

        public PolylineDrawer(Canvas canvasContent,  WinPropPolyline winShapeProp,WinPropCommon winProp)
        {
            PolylineCollection = new List<ASPNETX_WPFPolyline>();
            
            PolylineCanvas = canvasContent;
            winPolylineProp = winShapeProp;
            winCommonProp = winProp;

            _MouseType = TMouse.Drawing;

            MenuItem miFinish = new MenuItem();
            miFinish.Header = "Finish";
            miFinish.Click += new RoutedEventHandler(MenuItem_Finish_Click);

            MenuItem miDel = new MenuItem();
            miDel.Header = "Delete previous point";
            miDel.Click += new RoutedEventHandler(MenuItem_DelLastPoint_Click);

            MenuItem miClear = new MenuItem();
            miClear.Header = "Clear";
            miClear.Click += new RoutedEventHandler(MenuItem_Redraw_Click);

            cMenu.Items.Add(miFinish);
            cMenu.Items.Add(miDel);
            cMenu.Items.Add(miClear);

            RegistContextMenu();

            PolylineCanvas.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(polylineCanvas_MouseLeftButtonDown);
            PolylineCanvas.MouseMove += new System.Windows.Input.MouseEventHandler(polylineCanvas_MouseMove);

            BindListBox();
        }

        /// <summary>
        /// 注册上下文菜单，主要在模式切换里用
        /// </summary>
        public void RegistContextMenu()
        {
            if (MouseTye == TMouse.Drawing)
            {
                PolylineCanvas.ContextMenu = cMenu;
            }
            if (MouseTye == TMouse.Point)
            {
                PolylineCanvas.ContextMenu = null;
            }
        }

        public void Draw()
        {
            plBody = ResourceCenter.NewPolyline();
            PolylineCanvas.Children.Add(plBody.PolylineBody);
        }

        #region 处理鼠标事件
        void polylineCanvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (_MouseType == TMouse.Drawing)
            {
                if (plBody.PolylineBody.Points.Count > 0)
                {
                    Point p = e.GetPosition(PolylineCanvas);
                    int pgPointCount = plBody.PolylineBody.Points.Count;

                    if (IsShiftDown == false)
                    {
                        plBody.PolylineBody.Points[pgPointCount - 1] = p;
                    }
                    if (IsShiftDown == true)
                    {
                        if (pgPointCount > 1)
                        {
                            Point p1 = plBody.PolylineBody.Points[pgPointCount - 2];

                            double y = Math.Abs(p.Y - p1.Y);
                            double x = Math.Abs(p.X - p1.X);

                            
                            if (y / x < Math.Tan(45 * Math.PI / 180))
                            {
                                Point newPoint = new Point(p.X, p1.Y);

                                plBody.PolylineBody.Points[pgPointCount - 1] = newPoint;
                            }
                            if (y / x > Math.Tan(45 * Math.PI / 180))
                            {
                                Point newPoint = new Point(p1.X, p.Y);

                                plBody.PolylineBody.Points[pgPointCount - 1] = newPoint;
                            }
                            //if (y / x > Math.Tan(22.5 * Math.PI / 180) && y / x < Math.Tan(67.5 * Math.PI / 180))
                            //{
                            //    Point newPoint = new Point(p.X, p.X);

                            //    plBody.PolylineBody.Points[pgPointCount - 1] = newPoint;
                            //}
                        }
                    }

                    winPolylineProp.X = p.X;
                    winPolylineProp.Y = p.Y;
                }
            }
        }

        void polylineCanvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (_MouseType == TMouse.Drawing)
            {
                Point p = e.GetPosition(PolylineCanvas);

                //预览点
                //Rectangle rect = new Rectangle();
                //rect.Fill = new SolidColorBrush(Colors.Green);
                //rect.SetValue(Canvas.LeftProperty, p.X - 2.5);
                //rect.SetValue(Canvas.TopProperty, p.Y - 2.5);
                //rect.Width = 5;
                //rect.Height = 5;

                //polylineCanvas.Children.Add(rect);

                //int pgPointCount = plBody.PolylineBody.Points.Count;
                //plBody.PolylineBody.Points[pgPointCount - 1] = p;
                plBody.PolylineBody.Points.Add(p);

                winPolylineProp.lstPointsList.Items.Add("(" + p.X + "," + p.Y + ")");
            }
        }
        #endregion

        /// <summary>
        /// 绑定各层所添加的图形到列表
        /// </summary>
        public void BindListBox()
        {
            winCommonProp.lstHistory.Items.Clear();
            foreach (ASPNETX_WPFPolyline item in PolylineCollection)
            {
                winCommonProp.lstHistory.Items.Add(item.CommonProperty.Content);
            }
        }

        #region 上下文菜单的处理
        /// <summary>
        /// 上下文菜单的完成按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Finish_Click(object sender, RoutedEventArgs e)
        {
            if (plBody.PolylineBody.Points.Count > 1)
            {
                //1.移除最后一个点，因为其是昨预览线用的
                //2.设置基本属性值
                //3.将其添加到线序列，至此画线工作完成，为画下一组线做准备
                //4.新实例化一条线，并将其添加到画板中
                //5.绑定层次列表

                plBody.PolylineBody.Points.RemoveAt(plBody.PolylineBody.Points.Count - 1);

                plBody.CommonProperty.Index = winCommonProp.tbIndex.Text;
                plBody.CommonProperty.Content = winCommonProp.tbContent.Text;

                //lstHistory.Items.Add(plBody);
                PolylineCollection.Add(plBody);

                plBody = ResourceCenter.NewPolyline();
                winPolylineProp.lstPointsList.Items.Clear();

                PolylineCanvas.Children.Add(plBody.PolylineBody);

                BindListBox();
            }
            else
            {
                MessageBox.Show("Polyline has not finished yet!");
            }
        }

        /// <summary>
        /// 上下文菜单的删除上一个点按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_DelLastPoint_Click(object sender, RoutedEventArgs e)
        {
            if (plBody.PolylineBody.Points.Count > 2)
            {
                plBody.PolylineBody.Points.RemoveAt(plBody.PolylineBody.Points.Count - 1);

                //BindListBox();
            }
            else
            {
                MessageBox.Show("One point must be remain!");
            }
        }

        /// <summary>
        /// 上下文菜单重画按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Redraw_Click(object sender, RoutedEventArgs e)
        {
            PolylineCanvas.Children.Remove(plBody.PolylineBody);

            plBody = ResourceCenter.NewPolyline();

            PolylineCanvas.Children.Add(plBody.PolylineBody);
        }
        #endregion

        void PolylineBody_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (ASPNETX_WPFPolyline item in PolylineCollection)
            {
                item.PolylineBody.Fill = new SolidColorBrush(Colors.Blue);
            }

            Polyline mpline = (Polyline)sender;

            foreach (ASPNETX_WPFPolyline item in PolylineCollection)
            {
                if (item.PolylineBody == mpline)
                {
                    winPolylineProp.SetValue(item);

                    item.PolylineBody.Stroke = new SolidColorBrush(Colors.Red);

                    winCommonProp.tbIndex.Text = item.CommonProperty.Index;
                    winCommonProp.tbContent.Text = item.CommonProperty.Content;
                }
            }
        }
    }
}
